using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Byond.Vst.GlobalKeyLogger
{
	#region WINAPI Helper class

	/// <summary>
	/// Winapi Key interception helper class.
	/// </summary>
	internal static class InterceptKeys
	{
		public delegate IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam);

		public static int WH_KEYBOARD_LL = 13;

		public enum KeyEvent
		{
			WM_KEYDOWN = 256,
			WM_KEYUP = 257,
			WM_SYSKEYUP = 261,
			WM_SYSKEYDOWN = 260
		}

		public static IntPtr SetHook(LowLevelKeyboardProc proc)
		{
			using (var curProcess = Process.GetCurrentProcess())
				using (var curModule = curProcess.MainModule)
				{
					return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
						GetModuleHandle(curModule.ModuleName), 0);
				}
		}

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		public static extern bool UnhookWindowsHookEx(IntPtr hhk);

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, UIntPtr wParam, IntPtr lParam);

		[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr GetModuleHandle(string lpModuleName);
	}

	#endregion
}